[XEN] Avoid using regparm on a typedef.
authorIan Campbell <ian.campbell@xensource.com>
Thu, 23 Nov 2006 17:21:26 +0000 (17:21 +0000)
committerIan Campbell <ian.campbell@xensource.com>
Thu, 23 Nov 2006 17:21:26 +0000 (17:21 +0000)
This does not work reliably across gcc versions. Workaround this by attaching
the regparm attribute to a variable instead.

Also since guest_to_host_gpr_switch() updates the guest EAX on the stack there
is no need to do so in emulate_privileged_op() as well. Therefore io_emul stub
now returns void.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
xen/arch/x86/traps.c

index d015b6825dc8f9f9bb3cf1e9613b42e5bec589ef..120179d64036f2ce71b1d1dc72e85ce4e2d78e66 100644 (file)
@@ -1026,8 +1026,6 @@ void host_to_guest_gpr_switch(struct cpu_user_regs *)
     __attribute__((__regparm__(1)));
 unsigned long guest_to_host_gpr_switch(unsigned long)
     __attribute__((__regparm__(1)));
-typedef unsigned long (*io_emul_stub_t)(struct cpu_user_regs *)
-    __attribute__((__regparm__(1)));
 
 /* Instruction fetch with error handling. */
 #define insn_fetch(_type, _size, cs, eip)                                   \
@@ -1048,6 +1046,8 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
     u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0;
     unsigned int port, i, op_bytes = 4, data, rc;
     char io_emul_stub[16];
+    void (*io_emul)(struct cpu_user_regs *) __attribute__((__regparm__(1))) \
+        = (void*)&io_emul_stub[0];
     u32 l, h;
 
     /* Legacy prefixes. */
@@ -1204,22 +1204,20 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
         switch ( op_bytes )
         {
         case 1:
-            res = regs->eax & ~0xffUL;
             if ( guest_inb_okay(port, v, regs) )
-                regs->eax = res | (u8)((io_emul_stub_t)io_emul_stub)(regs);
+                io_emul(regs);
             else
-                regs->eax = res | (u8)~0;
+                regs->eax = (regs->eax & ~0xffUL) | (u8)~0;
             break;
         case 2:
-            res = regs->eax & ~0xffffUL;
             if ( guest_inw_okay(port, v, regs) )
-                regs->eax = res | (u16)((io_emul_stub_t)io_emul_stub)(regs);
+                io_emul(regs);
             else
-                regs->eax = res | (u16)~0;
+                regs->eax = (regs->eax & ~0xffffUL) | (u16)~0;
             break;
         case 4:
             if ( guest_inl_okay(port, v, regs) )
-                regs->eax = (u32)((io_emul_stub_t)io_emul_stub)(regs);
+                io_emul(regs);
             else
                 regs->eax = (u32)~0;
             break;
@@ -1244,15 +1242,15 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
         {
         case 1:
             if ( guest_outb_okay(port, v, regs) )
-                ((io_emul_stub_t)io_emul_stub)(regs);
+                io_emul(regs);
             break;
         case 2:
             if ( guest_outw_okay(port, v, regs) )
-                ((io_emul_stub_t)io_emul_stub)(regs);
+                io_emul(regs);
             break;
         case 4:
             if ( guest_outl_okay(port, v, regs) )
-                ((io_emul_stub_t)io_emul_stub)(regs);
+                io_emul(regs);
             break;
         }
         goto done;